package com.example.demo;

import java.awt.*;
import java.util.ArrayList;

public abstract class GameObject {
    //坐标
    private int x;
    private int y;
    //图片
    Image img;
    //游戏界面
    GameFrame gameFrame;
    //速度
    private int spd;
    //初始生命值
    private int hp;
    //当前生命值
    private int currentHp;
    //攻击目标
    private GameObject target;
    //是否有目标
    private boolean hasTarget = false;
    //攻击距离
    private int dis;
    //攻击时间间隔
    private int attackCoolDownTime;
    //攻击是否冷却
    private boolean attackCoolDown = true;
    //是否存活
    private boolean alive = true;


    public void setSpd(int spd) {
        this.spd = spd;
    }

    public int getSpd() {
        return spd;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public int getCurrentHp() {
        return currentHp;
    }

    public void setCurrentHp(int currentHp) {
        this.currentHp = currentHp;
    }

    public GameObject(GameFrame gameFrame){
        this.gameFrame = gameFrame;
    }
    public GameObject(GameFrame gameFrame, int x, int y){
        this.gameFrame = gameFrame;
        this.x = x;
        this.y = y;
    }

    public abstract Rectangle getRec();

    public abstract void paintSelf(Graphics g);

    //添加生命值
    public void addHp(Graphics g,int difX,int difY,int width,int height,Color color){
        //外部轮廓
        g.setColor(Color.BLACK);
        g.drawRect(getX() - difX,getY() - difY,width,height);
        //生命条
        g.setColor(color);
        g.fillRect(getX() - difX,getY() - difY,(int) (width * getCurrentHp()/getHp()),height);
    }

    //矩形和矩形的碰撞检测
    public boolean revIntersectsRec(Rectangle r1,Rectangle r2){
        return r1.intersects(r2);
    }
    //矩形和圆形的碰撞检测
    public boolean revIntersectsCir(Rectangle rec,int x,int y,int r){
        if ((getDis(x,y,rec.x,rec.y) < r)
            || (getDis(x,y,rec.x,rec.y+rec.height) < r)
            || (getDis(x,y,rec.x+rec.width,rec.y) < r)
            || (getDis(x,y,rec.x+rec.width,rec.y+rec.height) < r)){
            return true;
        }
//        if (Math.abs(x - rec.x) < r || Math.abs(x - (rec.x + rec.width)) < r){
//            return true;
//        }
//        if (Math.abs(y - rec.y) < r || Math.abs(y - (rec.y + rec.height)) < r){
//            return true;
//        }
        return false;
    }
    //攻击方法
    public void attack(ArrayList<GameObject> gameObjList){
        if (hasTarget){
            //目标离开范围后寻找新的目标
            if (!revIntersectsCir(target.getRec(),getX(),getY(),getDis())){
                setHasTarget(false);
            }//目标死亡，寻找新目标
            else if (!target.isAlive()){
                setHasTarget(false);
            }else if (isAttackCoolDown() && isAlive()){
                Bullet bullet = null;
                //防御塔攻击
                if (Turret.class.isAssignableFrom(getClass())) {
                    bullet = new Bullet(gameFrame,this,getTarget(),500,50);
                }
                //小兵攻击
                else if (Minion.class.isAssignableFrom(getClass())) {
                    bullet = new Bullet(gameFrame,this,getTarget(),50,30);
                }
                //玩家攻击
                else if (this instanceof Champion){
                    bullet = new Bullet(gameFrame,this,getTarget(),500,50);
                }
                gameFrame.objList.add(bullet);
                //线程开始
                new AttackCD().start();
            }
        }else {
            //遍历列表
            for (GameObject obj : gameObjList){
                //判断攻击范围(圆形)与敌方（矩形）是否相交
                if (revIntersectsCir(obj.getRec(),getX(),getY(),getDis())){
                    //找到目标
                    setTarget(obj);
                    setHasTarget(true);
                    //跳出循环
                    break;
                }
            }
            //玩家是否在攻击范围内
            if (!hasTarget && gameObjList == gameFrame.blueList){
                if (revIntersectsCir(gameFrame.player.getRec(),getX(),getY(),getDis())){
                    //找到目标
                    target = gameFrame.player;
                    hasTarget = true;
                }
            }
        }
    }

    class AttackCD extends Thread{
        public void run(){
            //将攻击功能设置为冷却状态
            setAttackCoolDown(false);
        //线程休眠
        try{
            Thread.sleep(attackCoolDownTime);
        }catch (Exception e){
            e.printStackTrace();
        }
            //将攻击功能设置为攻击状态
            setAttackCoolDown(true);
        //线程终止
            this.stop();
    }
    }

    //获取两点之间的距离
    public double getDis(int x1,int y1,int x2,int y2){
        return Math.sqrt(Math.pow(x1 - x2,2) + Math.pow(y1 - y2,2));
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public Image getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = Toolkit.getDefaultToolkit().getImage(img);
    }

    public GameFrame getGameFrame() {
        return gameFrame;
    }

    public void setGameFrame(GameFrame gameFrame) {
        this.gameFrame = gameFrame;
    }

    public GameObject getTarget() {
        return target;
    }

    public void setTarget(GameObject target) {
        this.target = target;
    }

    public boolean isHasTarget() {
        return hasTarget;
    }

    public void setHasTarget(boolean hasTarget) {
        this.hasTarget = hasTarget;
    }

    public int getDis() {
        return dis;
    }

    public void setDis(int dis) {
        this.dis = dis;
    }

    public int getAttackCoolDownTime() {
        return attackCoolDownTime;
    }

    public void setAttackCoolDownTime(int attackCoolDownTime) {
        this.attackCoolDownTime = attackCoolDownTime;
    }

    public boolean isAttackCoolDown() {
        return attackCoolDown;
    }

    public void setAttackCoolDown(boolean attackCoolDown) {
        this.attackCoolDown = attackCoolDown;
    }
    public boolean isAlive() {
        return alive;
    }

    public void setAlive(boolean alive) {
        this.alive = alive;
    }
}
